package com.springboot.module.user.service.user;

import com.fasterxml.jackson.databind.util.BeanUtil;
import com.springboot.module.user.controller.user.vo.UserExportResVo;
import com.springboot.module.user.controller.user.vo.UserReqVo;
import com.springboot.module.user.controller.user.vo.UserResVo;
import com.springboot.module.user.controller.user.vo.UserSaveReqVo;
import com.springboot.module.user.dal.dataobject.dept.SysDept;
import com.springboot.module.user.dal.dataobject.permission.SysUserRole;
import com.springboot.module.user.dal.dataobject.user.SysUser;
import com.springboot.module.user.dal.mysql.dept.DeptMapper;
import com.springboot.module.user.dal.mysql.permission.UserRoleMapper;
import com.springboot.module.user.dal.mysql.user.UserMapper;
import com.springboot.module.user.utils.aop.LogOperation;
import com.springboot.module.user.utils.jwtUtilis.JwtUtils;
import com.sun.xml.bind.v2.TODO;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

import java.util.stream.Collectors;

import static com.springboot.module.user.controller.user.vo.PageParams.PAGE_SIZE_NONE;


@Service
@Slf4j
public class UserServiceImpl implements UserService{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;
    @Override
    public UserResVo login(UserReqVo userReqVo) {
        SysUser user = userMapper.userLogin(userReqVo.getUsername(),userReqVo.getPassword());
        log.debug(String.valueOf(user));
        if (user != null) {
            // 1. 生成JWT令牌
            Map<String, Object> dataMap = new HashMap<>();
            dataMap.put("id", user.getId());
            dataMap.put("username", user.getUsername());
            String token = JwtUtils.generateJwt(dataMap);
            UserResVo userResVo = new UserResVo();
            BeanUtils.copyProperties(user, userResVo);
            userResVo.setToken(token);
            userResVo.setDeptId(user.getDeptId());

            return userResVo;
        }
        return null;
    }

    @Override
    public List<UserResVo> selectAll() {
        return userMapper.getAll().stream()
                .map(user -> {
                    UserResVo userResVo = new UserResVo();
                    BeanUtils.copyProperties(user, userResVo);
                    return userResVo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public UserResVo getById(Long id) {
        SysUser user = userMapper.selectById(id);
        if(user==null){
            return null;
        }
        log.debug(String.valueOf(user.getDeptId()));
        return getDeptByUser(user);
    }

    private UserResVo getDeptByUser(SysUser user) {
        Integer deptId = user.getDeptId();
        SysDept sysDept = deptMapper.selectDeptNameByDeptId(deptId);
        UserResVo userResVo = new UserResVo();
        BeanUtils.copyProperties(user,userResVo);
        userResVo.setDeptId(deptId);
        userResVo.setDeptName(sysDept.getDeptName());
        return userResVo;
    }

    @Override
    public List<UserResVo> page(UserReqVo userReqVo) {
        Integer pageNumber = userReqVo.getPageNumber();
        Integer pageSize = userReqVo.getPageSize();
        Integer start = pageNumber - 1;
        List<SysUser> sysUsers = userMapper.pageResult(start, pageSize);
        List<UserResVo> userResVos = sysUsers.stream().map(sysUser -> getDeptByUser(sysUser)).collect(Collectors.toList());
        return userResVos;
    }

    //还未实现
    @Override
    public List<UserReqVo> likePage(UserReqVo userReqVo) {
        userMapper.likeSelect(userReqVo);
        return null;
    }

    @Override
    public Long saveUser(UserSaveReqVo userSaveReqVo) {
        SysUser user = new SysUser();
        BeanUtils.copyProperties(userSaveReqVo,user);
        userMapper.saveUser(user);
        return user.getId();
    }

    @Override
    @Transactional
    public void deleteById(Long id) {
        //先判断ID是否存在
        SysUser user = userMapper.selectById(id);
        if(user == null){
            throw new RuntimeException("删除用户不存在");
        }
        //先删除与之绑定的角色
        //先查询用户是否含有该角色
        List<SysUserRole> sysUserRole = userRoleMapper.selectById(id);
        if(sysUserRole != null){
            userRoleMapper.deleteById(id);
        }
        //再删除用户
        userMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void deleteBatch(Set<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("删除ID列表不能为空");
        }
        // 校验用户是否存在（可选）
        Set<Long> existIds = userMapper.checkExist(ids);
        if (existIds.size() < ids.size()) {
            throw new RuntimeException("部分用户不存在，ID: " +
                    ids.stream().filter(id -> !existIds.contains(id)).collect(Collectors.toList()));
        }
        //先删除用户角色关联数据
        for (Long id : ids) {
            List<SysUserRole> sysUserRoles = userRoleMapper.selectById(id);
           if(sysUserRoles !=null){
               userRoleMapper.deleteById(id);
           }
        }
        // 执行删除
        userMapper.deleteBatch(ids);
    }

    @Override
    public void updateUser(UserSaveReqVo userSaveReqVo) {
        //此处不设密码
        // 1. 校验正确性
        validateUserForCreateOrUpdate( userSaveReqVo.getId(),  userSaveReqVo.getUsername(),
                userSaveReqVo.getPhone(), userSaveReqVo.getStatus(), userSaveReqVo.getDeptId());

        // 2.1 更新用户
        SysUser updateObj = new SysUser();
        BeanUtils.copyProperties(userSaveReqVo,updateObj);

        userMapper.updateById(updateObj);
    }

    @Override
    @LogOperation
    public void exportExcel() {
        // 导出所有数据查所有
        List<SysUser> sysUsers = userMapper.getAll();
        List<UserExportResVo> users = sysUsers.stream().map(sysUser -> {
            UserExportResVo userExportResVo = new UserExportResVo();
            BeanUtils.copyProperties(sysUser, userExportResVo);
            Integer deptId = sysUser.getDeptId();
            SysDept sysDept = deptMapper.selectDeptNameByDeptId(deptId);
            // 修正部门名称的设置，假设 UserExportResVo 的 deptName 是 String 类型
            userExportResVo.setDeptName(sysDept != null ? sysDept.getDeptName() : "");
            return userExportResVo;
        }).collect(Collectors.toList());

        // 将数据导出 Excel
        // 创建一个 XSSFWorkbook
        Workbook workbook = new XSSFWorkbook();
        // 创建一个 sheet
        Sheet sheet = workbook.createSheet();
        // 创建表头行
        Row headerRow = sheet.createRow(0);

        // 设置表头
        String[] headers = {"用户ID", "用户名称", "用户邮箱", "手机号", "部门名称"};
        for (int i = 0; i < headers.length; i++) {
            Cell cell = headerRow.createCell(i);
            cell.setCellValue(headers[i]);
        }

        // 填充数据
        for (int rowNum = 0; rowNum < users.size(); rowNum++) {
            UserExportResVo user = users.get(rowNum);
            Row row = sheet.createRow(rowNum + 1); // +1 是因为第0行已经是表头

            // 设置每行的数据
            row.createCell(0).setCellValue(user.getId() != null ? user.getId().toString() : "");
            row.createCell(1).setCellValue(user.getUsername() != null ? user.getUsername(): "");
            row.createCell(2).setCellValue(user.getEmail()!= null ? user.getEmail() : "");
            row.createCell(3).setCellValue(user.getPhone() != null ? user.getPhone() : "");
            row.createCell(4).setCellValue(user.getDeptName() != null ? user.getDeptName() : "");
        }

        // 自动调整列宽
        for (int i = 0; i < headers.length; i++) {
            sheet.autoSizeColumn(i);
        }

        // 写入文件
        try (FileOutputStream out = new FileOutputStream("用户表.xlsx")) {
            workbook.write(out);
            System.out.println("Excel 导出完成");
        } catch (IOException e) {
            e.printStackTrace();
            // 可以考虑抛出异常或返回错误信息
        } finally {
            try {
                workbook.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }

    private SysUser validateUserForCreateOrUpdate(Long id, String username, String phone, Integer status, Integer deptId) {
        
            // 校验用户存在
            SysUser user = validateUserExists(id);
            // 校验用户名唯一
            validateUsernameUnique(id, username);
            // 校验手机号唯一
            validateMobileUnique(id, phone);
            // 校验部门处于开启状态
            validateDeptStatus(deptId);
            return user;
       
    }

    void validateDeptStatus(Integer deptId) {
        SysDept sysDept = deptMapper.queryDeptStatus(deptId);
        if (sysDept.getStatus() == 0) {
                throw new RuntimeException("部门处于金庸状态");
            }
    }
    void validateMobileUnique(Long id, String phone) {
        if (phone==null) {
            return;
        }
        SysUser user = userMapper.selectByMobile(phone);
        if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw new RuntimeException("用户手机号存在");
        }
        if (!user.getId().equals(id)) {
            throw new RuntimeException("用户手机号存在");
        }
    }

    void validateUsernameUnique(Long id, String username) {
        if (username==null) {
            return;
        }
       SysUser user = userMapper.selectByUsername(username);
       if (user == null) {
            return;
        }
        // 如果 id 为空，说明不用比较是否为相同 id 的用户
        if (id == null) {
            throw new RuntimeException("用户用户名存在");
        }
        if (!user.getId().equals(id)) {
            throw new RuntimeException("用户用户名存在");
        }
    }

    private SysUser validateUserExists(Long id) {
        if (id == null) {
            return null;
        }
        SysUser user = userMapper.selectById(id);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        return user;
    }
}
